<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>
    var Event = (function () {
      var global = this,
        Event,
        _default = 'default';
      Event = function () {
        var _listen,
          _trigger,
          _remove,
          _slice = Array.prototype.slice,
          _shift = Array.prototype.shift,
          _unshift = Array.prototype.unshift,
          namespaceCache = {},
          _create,
          find,
          each = function (ary, fn) {
            var ret;
            for (var i = 0, l = ary.length; i < l; i++) {
              var n = ary[i];
              ret = fn.call(n, i, n);
            }
            return ret;
          };
        _listen = function (key, fn, cache) {
          if (!cache[key]) {
            cache[key] = [];
          }
          cache[key].push(fn);
        };
        _remove = function (key, cache, fn) {
          if (cache[key]) {
            if (fn) {
              for (var i = cache[key].length; i >= 0; i--) {
                if (cache[key][i] === fn) {
                  cache[key].splice(i, 1);
                }
              }
            } else {
              cache[key] = [];
            }
          }
        };
        _trigger = function () {
          var cache = _shift.call(arguments),
            key = _shift.call(arguments),
            args = arguments,
            _self = this,
            ret,
            stack = cache[key];
          if (!stack || !stack.length) {
            return;
          }
          return each(stack, function () {
            return this.apply(_self, args);
          });
        };
        _create = function (namespace) {
          var namespace = namespace || _default;
          var cache = {},
            offlineStack = []; // 离线事件
          var ret = {
            listen: function (key, fn, last) {
              _listen(key, fn, cache);
              console.log(offlineStack)
              if (offlineStack === null) {
                return;
              }
              if (last === 'last') {
                offlineStack.length && offlineStack.pop()();
              } else {
                each(offlineStack, function () {
                  this();
                });
              }
              offlineStack = null;
            },
            one: function (key, fn, last) {
              _remove(key, cache);
              this.listen(key, fn, last);
            },
            remove: function (key, fn) {
              _remove(key, cache, fn);
            },
            trigger: function () {
              var fn,
                args,
                _self = this;
              _unshift.call(arguments, cache);
              args = arguments;
              fn = function () {
                return _trigger.apply(_self, args);
              };
              if (offlineStack) {
                return offlineStack.push(fn);
              }
              return fn();
            }
          };
          return namespace ?
            (namespaceCache[namespace] ? namespaceCache[namespace] :
              namespaceCache[namespace] = ret)
            : ret;
        };
        return {
          create: _create,
          one: function (key, fn, last) {
            var event = this.create();
            event.one(key, fn, last);
          },
          remove: function (key, fn) {
            var event = this.create();
            event.remove(key, fn);
          },
          listen: function (key, fn, last) {
            var event = this.create();
            event.listen(key, fn, last);
          },
          trigger: function () {
            var event = this.create();
            event.trigger.apply(this, arguments);
          }
        };
      }();
      return Event;
    })();
    Event.trigger('click', 1);
    Event.listen('click', function (a) {
      console.log(a); // 输出：1
    });

  </script>
</body>

</html>